package com.zy.core.data.jpa.support.manager.impl;

import com.zy.core.data.jpa.support.entity.BaseEntity;
import com.zy.core.data.jpa.support.entity.page.Pagination;
import com.zy.core.data.jpa.support.manager.BaseManager;
import com.zy.core.data.jpa.support.repository.BaseRepository;
import com.zy.core.util.Updater;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

@Transactional(readOnly=true)
public abstract class BaseManagerImpl<T extends BaseEntity, ID extends Serializable> implements BaseManager<T, ID> {

	public abstract BaseRepository<T, ID> getDao();

	@Override
	public T findById(ID id) {
		return this.getDao().findOne(id);
	}

	@Override
	public List<T> findAll() {
		return this.getDao().findAll();
	}

	@Override
	public List<T> findList(ID[] ids) {
		List<ID> idList = Arrays.asList(ids);
		return this.getDao().findAllById(idList);
	}

	@Override
	public List<T> findList(Iterable<ID> ids) {
		return this.getDao().findAllById(ids);
	}

	@Override
	public Pagination<T> findAll(int pageNo, int pageSize) {
		//Pageable pageable = new PageRequest(pageNo, pageSize);
		Pageable pageable = PageRequest.of(pageNo == 0 ? 0 : pageNo - 1,pageSize);
		Page<T> page = this.getDao().findAll(pageable);
		Long total =new Long(page.getTotalElements());
		Pagination<T> pagination = new Pagination<T>(pageNo, pageSize,
				total.intValue(), page.getContent());
		return pagination;
	}

	@Override
	public long count() {
		return this.getDao().count();
	}

	@Override
	public boolean exists(ID id) {
		return this.getDao().existsById(id);
	}

	@Override
	@Transactional(readOnly=false)
	public T save(T entity) {
		return this.getDao().save(entity);
	}

	@Override
	@Transactional(readOnly=false)
	public T update(T entity) {
		Updater<T> updater = new Updater<T>(entity);
		return this.getDao().updateByUpdater(updater);
	}

	@Override
	@Transactional(readOnly=false)
	public T update(T entity, String[] includePropertys,
			String[] excludePropertys) {
		Updater<T> updater = new Updater<T>(entity);
		if(includePropertys!=null && includePropertys.length>0){
			for(String include : includePropertys){
				//必须更新的字段
				updater.include(include);
			}
		}
		if(excludePropertys!=null && excludePropertys.length>0){
			for(String exclude : excludePropertys){
				//不需要更新的字段
				updater.exclude(exclude);
			}
		}
		return this.getDao().updateByUpdater(updater);
	}

	@Override
	@Transactional(readOnly=false)
	public void deleteById(ID id) {
		this.getDao().deleteById(id);
	}

	@Override
	@Transactional(readOnly=false)
	public void deleteByIds(ID... ids) {
		if (ids != null) {
			for (int i = 0; i < ids.length; i++) {
				ID id = ids[i];
				this.deleteById(id);
			}
		}
	}

	@Override
	@Transactional(readOnly=false)
	public void delete(T[] entitys) {
		List<T> ls=Arrays.asList(entitys);
		this.getDao().deleteInBatch(ls);
	}

	@Override
	@Transactional(readOnly=false)
	public void delete(Iterable<T> entitys) {
		this.getDao().deleteInBatch(entitys);
	}

	@Override
	@Transactional(readOnly=false)
	public void delete(T entity) {
		this.getDao().delete(entity);
	}

	@Override
	@Transactional(readOnly=false)
	public List<T> save(Iterable<T> iterable){

		return this.getDao().saveAll(iterable);
	}


}